package work.mediway.mdm.biz.service.dict.impl;

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mediway.hos.app.base.seure.util.SecurityUtils;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import work.mediway.mdm.core.enums.StatusCodingRuleEnum;
import work.mediway.mdm.core.enums.StatusEnum;
import work.mediway.mdm.core.exception.DataException;
import work.mediway.mdm.core.page.QueryRequest;
import work.mediway.mdm.core.util.DUtil;
import work.mediway.mdm.biz.mapper.dict.CtCodeSystemMapper;
import work.mediway.mdm.biz.vo.dict.CtCodeSystemVO;
import work.mediway.mdm.biz.vo.dict.DictListVO;
import work.mediway.mdm.biz.dto.dict.CodeSystemDTO;
import work.mediway.mdm.biz.dto.dict.DictListDTO;
import work.mediway.mdm.biz.entity.dict.CtCodeSystem;
import work.mediway.mdm.biz.service.dict.CtCodeSystemService;

/**
 * @author zhongyj <1126834403@qq.com><br/>
 * @date 2021/1/6
 */
@SuppressWarnings("DuplicatedCode")
@Slf4j
@Transactional(rollbackFor = Exception.class)
@Service
public class CtCodeSystemServiceImpl extends ServiceImpl<CtCodeSystemMapper, CtCodeSystem> implements CtCodeSystemService {

    @Override
    public Page<DictListVO> pageCodeSystem(DictListDTO dictDTO) {
        if (StrUtil.isNotBlank(dictDTO.getDataCountStart()) || StrUtil.isNotBlank(dictDTO.getDataCountEnd())) {
            dictDTO.setSize(Integer.MAX_VALUE);
        }
        if (ObjectUtil.isAllEmpty(dictDTO.getUserId(), dictDTO.getRoleId())) {
            dictDTO.setUserId(SecurityUtils.getUserId());
            dictDTO.setRoleId(SecurityUtils.getSingleUserRoleId());
        }

        Page<DictListVO> page = new Page<>(dictDTO.getCurrent(), dictDTO.getSize());
        page.setOrders(OrderItem.descs("CTCS_DataCount"));
        page.setRecords(this.baseMapper.listCodeSystem(page, dictDTO));

        page.getRecords().forEach(i -> {
            i.setCodingRuleDesc(StatusCodingRuleEnum.map.get(i.getCodingRule()));
            i.setStatusDesc(StatusEnum.map.get(i.getStatus()));
        });
        return page;
    }

    @Override
    public Page<DictListVO> pageCodeSystemAll(DictListDTO dictDTO, QueryRequest queryRequest) {
        if (StrUtil.isNotBlank(dictDTO.getDataCountStart()) || StrUtil.isNotBlank(dictDTO.getDataCountEnd())) {
            queryRequest.setSize(Integer.MAX_VALUE);
        }

        Page<DictListVO> page = new Page<>(queryRequest.getCurrent(), queryRequest.getSize());
        page.setOrders(OrderItem.ascs("CTCS_DataCount"));
        page.setRecords(this.baseMapper.listCodeSystem(page, dictDTO));

        page.getRecords().forEach(i -> {
            i.setCodingRuleDesc(StatusCodingRuleEnum.map.get(i.getCodingRule()));
            i.setStatusDesc(StatusEnum.map.get(i.getStatus()));
        });
        return page;
    }

    @Override
    public void modifyDictTable(CodeSystemDTO codeSystemDTO) {
        if (StrUtil.isBlank(codeSystemDTO.getCodeSystemCode())) {
            throw new DataException(StrUtil.format("更新信息代码时 codeSystemCode = 【{}】不能为空", codeSystemDTO.getCodeSystemCode()));
        }
        codeSystemDTO.setLastUpdateUserId(SecurityUtils.getLoginName());
        CtCodeSystem one = this.getOne(Wrappers.lambdaQuery(CtCodeSystem.class).eq(CtCodeSystem::getCodeSystemCode, codeSystemDTO.getCodeSystemCode()));
        if (ObjectUtil.isEmpty(one)) {
            CtCodeSystem codeSystem = BeanUtil.copyProperties(codeSystemDTO, CtCodeSystem.class);
            codeSystem.setLastUpdateDate(DUtil.splitNow()[0]);
            codeSystem.setLastUpdateTime(DUtil.splitNow()[1]);
            codeSystem.setUpdateDate(DUtil.splitNow()[1]);
            codeSystem.setUpdateTime(DUtil.splitNow()[1]);
            this.save(codeSystem);
            return;
        }
        BeanUtil.copyProperties(codeSystemDTO, one, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        one.setLastUpdateDate(DUtil.splitNow()[0]);
        one.setLastUpdateTime(DUtil.splitNow()[1]);
        this.updateById(one);
    }

    @Override
    public void updateDataCountByCodeBatch(List<CodeSystemDTO> codeSystems) {
        this.baseMapper.updateDataCountByCodeBatch(codeSystems);
    }

    @Override
    public void updateDataCountByCode(CodeSystemDTO codeSystemDTO) {
        this.baseMapper.updateDataCountByCode(codeSystemDTO);
    }

    @Override
    public List<CtCodeSystemVO> selectAllTable(CodeSystemDTO codeSystem, QueryRequest queryRequest) {
        if (StrUtil.containsAnyIgnoreCase(codeSystem.getCodeSystemCode(), "_")) {
            codeSystem.setCodeSystemCode(StrUtil.replace(codeSystem.getCodeSystemCode(), "_", "\\_"));
        }

        Page<CtCodeSystemVO> page = new Page<>(queryRequest.getCurrent(), queryRequest.getSize());
        page.setRecords(this.baseMapper.selectAllTable(page, codeSystem));

        page.getRecords().forEach(item -> item.setStatusDesc(StatusEnum.map.get(item.getStatus())));
        return page.getRecords();
    }

    @Override
    public void saveCodeSystem(CtCodeSystem codeSystem) {
        if (StrUtil.isEmpty(codeSystem.getCodeSystemDesc())) {
            codeSystem.setCodeSystemDesc("");
        }
        codeSystem.setLastUpdateUserId(SecurityUtils.getLoginName());
        codeSystem.setLastUpdateDate(DUtil.splitNow()[0]);
        codeSystem.setLastUpdateTime(DUtil.splitNow()[1]);
        codeSystem.setStatus(StatusEnum.STATUS_ACTIVE.getStatusCode());
        codeSystem.setSaveTableClass("");
        codeSystem.setEvaluTableClass("");
        codeSystem.setCodeSystemCat("");
        this.save(codeSystem);
    }

    @Override
    public void updateCodeSystemByCode(CtCodeSystem codeSystem) {
        if (StrUtil.isEmpty(codeSystem.getCodeSystemDesc())) {
            codeSystem.setCodeSystemDesc("");
        }
        codeSystem.setLastUpdateUserId(SecurityUtils.getLoginName());
        codeSystem.setLastUpdateDate(DUtil.splitNow()[0]);
        codeSystem.setLastUpdateTime(DUtil.splitNow()[1]);
        this.updateById(codeSystem);
    }
}